package com.pay.enums;

/* ***************************************
 *                                       *
 *  @dookay.com Internet make it happen  *
 *  ----------- -----------------------  *
 *  d d d   d d d  Defending your name   *
 *  o    o      o  I am here, as always  *
 *  k     k     k  As the Goddess wills  *
 *  a    a      a  Your magic is mine    *
 *  y y y   y y y  Don't worry Be happy  *
 *  ----------- -----------------------  *
 *  @dookay.com Internet make it happen  *
 *            认真写BUG                  *
 *               LGY                     *
 ****************************************/


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.pay.util.AlipayConfig;
import com.pay.util.PayParameter;
import com.pay.util.YinLianPayConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public enum PayEnums {



    /**
     * 阿里签名
     */
    A_LI_PAY {
        @Override
        public Map<String, Object> getPaySign(PayParameter payParameter) throws AlipayApiException {
            Logger logger = LoggerFactory.getLogger(PayEnums.class);
            Map<String, Object> map = new HashMap<>();
            BigInteger paySn = payParameter.getPaySn();
            String advancePaymentMoney = payParameter.getAdvancePaymentMoney();
            String notifyUrl = payParameter.getNotifyUrl();
            String payOrdersType = payParameter.getPayType();
            AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                    AlipayConfig.app_id, AlipayConfig.private_key, "json", "UTF-8", AlipayConfig.ali_public_key, AlipayConfig.sign_type);
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setBody(payOrdersType);
            //商品订单编号
            model.setSubject("商品订单" + paySn);
            logger.info("paySn----------------->" + paySn);
            //商品标号
            model.setOutTradeNo(String.valueOf(paySn));
            //输出时长
            model.setTimeoutExpress("30m");
            //订单金额
            model.setTotalAmount(advancePaymentMoney);
            model.setProductCode("QUICK_MSECURITY_PAY");
            request.setBizModel(model);
            request.setNotifyUrl(notifyUrl);
            logger.info("设置的支付宝NotifyUrl是----------》" + request.getNotifyUrl());
            request.setApiVersion("1.0");
            request.setReturnUrl("http://www.hrjs.cn/");
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            logger.info("签名完成," + response.getBody());
            map.put("response", response);
            return map;
        }
    },
    /**
     * 微信签名
     */
    W_X_PAY {
        @Override
        public Map<String, Object> getPaySign(PayParameter payParameter) throws Exception {
            Logger logger = LoggerFactory.getLogger(PayEnums.class);
            //调用统一下单API得到预支付Id
            logger.info("调用统一下单API得到预支付Id");
            Map<String, Object> map = new HashMap<>();
            String Money = payParameter.getAdvancePaymentMoney();
            BigDecimal advancePaymentMoney = new BigDecimal(Money);
            String notifyUrl = payParameter.getNotifyUrl();
            String payOrdersType = payParameter.getPayType();
            BigInteger paySn = payParameter.getPaySn();

            HashMap<String, Object> payInfo = new HashMap();
            payInfo.put("payOrdersType", payOrdersType);
            payInfo.put("paySn", paySn);
            payInfo.put("subject", "商品订单" + paySn);
            payInfo.put("payAmount", advancePaymentMoney);
            payInfo.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
            payInfo.put("notifyUrl", notifyUrl);
            //初始配置信息
            WxPayConfigure wxPayConfigure = new WxPayConfigure();
            wxPayConfigure.setKey(WxpayConfig.wxKey);
            wxPayConfigure.setAppID(WxpayConfig.wxAppId);
            wxPayConfigure.setMchID(WxpayConfig.wxMchid);
            WxpayApp wxpayApp = new WxpayApp(wxPayConfigure, payInfo);
            String prepayId = wxpayApp.getPrepayId();
            logger.info("组成支付内容返回给APP");
            HashMap<String, Object> param = new HashMap<>();
            param.put("appid", WxpayConfig.wxAppId);
            param.put("partnerid", WxpayConfig.wxMchid);
            param.put("prepayid", prepayId);
            param.put("noncestr", payInfo.get("nonce_str"));
            param.put("timestamp", ShopHelper.getCurrentTime());
            param.put("package", "Sign=WXPay");
            logger.info("得到prepayId后再次签名");
            param.put("sign", Signature.getSign(param, wxPayConfigure));
            map.put("response", param);
            return map;
        }
    },
    YIN_LIAN_PAY {
        @Override
        public Map<String, Object> getPaySign(PayParameter payParameter) throws Exception {
            Logger logger = LoggerFactory.getLogger(PayEnums.class);
            Map<String, Object> map = new HashMap<>();
            String advancePaymentMoney = payParameter.getAdvancePaymentMoney();
            BigDecimal yuan = new BigDecimal(advancePaymentMoney);
            BigDecimal fen = new BigDecimal(100);
            BigInteger money = yuan.multiply(fen).toBigInteger();
            logger.info("money转换为分后--#############-------------##########------------######" + money.toString());
            String payOrdersType = payParameter.getPayType();
            String notifyUrl = payParameter.getNotifyUrl();
            BigInteger paySn = payParameter.getPaySn();
            String ordersType = payParameter.getOrdersType();
            logger.info("请求报文PayParameter---------------》"+payParameter.toString());
            YinLianPayConfig ylPayConfig = new YinLianPayConfig();
            //组织请求报文
            JSONObject json = new JSONObject();
            json.put("mid", ylPayConfig.getMid());
            json.put("tid", ylPayConfig.getTid());
            json.put("msgType", payOrdersType);
            json.put("msgSrc", ylPayConfig.getMsgSrc());
            json.put("instMid", ylPayConfig.getInstMid());
            json.put("merOrderId", YinLianPayConfig.getMsgSrcId() + paySn.toString());
            //支付金额改为1分钱，方便测试，上线后更改
            json.put("totalAmount", 1);
            json.put("notifyUrl", notifyUrl);
            json.put("tradeType", "APP");
            if (null != ordersType) {
                json.put("attachedData", ordersType);
            }
            //是否要在商户系统下单，看商户需求  createBill()
            json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

            Map<String, String> paramsMap = PayUtil.jsonToMap(json);
            paramsMap.put("sign", PayUtil.makeSign(YinLianPayConfig.getMd5Key(), paramsMap));
            logger.info("paramsMap：" + paramsMap);

            String strReqJsonStr = JSON.toJSONString(paramsMap);
            logger.info("strReqJsonStr：" + strReqJsonStr);
            //调用银商平台获取二维码接口
            HttpURLConnection httpURLConnection = null;
            BufferedReader in = null;
            OutputStreamWriter out = null;
            String resultStr = null;
            Map<String, String> resultMap = new HashMap<String, String>();
            if (!StringUtils.isNotBlank(ylPayConfig.getAPIurl())) {
                resultMap.put("errCode", "URLFailed");
                resultStr = JSONObject.fromObject(resultMap).toString();
                map.put("response", resultStr);
                return map;
            }

            try {
                URL url = new URL(ylPayConfig.getAPIurl());
                httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoInput(true);
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setRequestProperty("Content_Type", "application/json");
                httpURLConnection.setRequestProperty("Accept_Charset", "UTF-8");
                httpURLConnection.setRequestProperty("contentType", "UTF-8");
                //发送POST请求参数
                out = new OutputStreamWriter(httpURLConnection.getOutputStream(), "utf-8");
                out.write(strReqJsonStr);
                out.flush();

                //读取响应
                if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    StringBuffer content = new StringBuffer();
                    String tempStr = null;
                    in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
                    while ((tempStr = in.readLine()) != null) {
                        content.append(tempStr);
                    }
                    logger.info("content：" + content.toString());

                    //转换成json对象
                    com.alibaba.fastjson.JSONObject respJson = JSON.parseObject(content.toString());
                    String resultCode = respJson.getString("errCode");
                    resultMap.put("errCode", resultCode);
                    resultMap.put("respStr", respJson.toString());
                    Map<String, String> req = null;
                    if (respJson.containsKey("appPayRequest")) {
                        Map appPayRequest = (Map) respJson.get("appPayRequest");
                        if (appPayRequest.containsKey("qrCode")) {
                            String value = (String) appPayRequest.get("qrCode");
                            req = new HashMap<>();
                            req.put("qrCode", value);
                        } else if (appPayRequest.containsKey("tn")) {
                            String value = (String) appPayRequest.get("tn");
                            req = new HashMap<>();
                            req.put("tn", value);
                        }
                        map.put("response", req);
                    } else {
                        map.put("errMessage", resultCode);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                resultMap.put("errCode", "HttpURLException");
                resultMap.put("msg", "调用银商接口出现异常：" + e.toString());
                resultStr = JSONObject.fromObject(resultMap).toString();
                map.put("response", resultStr);
                return map;
            } finally {
                if (out != null) {
                    out.close();
                }
                httpURLConnection.disconnect();
            }
            logger.info("resultStr：" + resultStr);
            return map;
        }
    };

    public abstract Map<String, Object> getPaySign(PayParameter payParameter) throws Exception;

}
